package fr.ece.ing4.si.MonteCarlo.Application;

import java.io.IOException;

import fr.ece.ing4.si.MonteCarlo.Calculation.MonteCarloSimulation;
import fr.ece.ing4.si.MonteCarlo.Calculation.MultiThreadedVersion.MonteCarloThreadedSimulation;
import fr.ece.ing4.si.MonteCarlo.Calculation.SingleThreadedVersion.MonteCarloSequentialSimulation;

import java.util.concurrent.ExecutionException;

import fr.ece.ing4.si.MonteCarlo.Interface.*;

/**
 * 
 * @author matt
 * Controller of the Monte Carlo Application.
 */
public class MonteCarlo
{
	public static double result=0;
	public static long timeResult=0;
	public static int coresNb=0;
	public static int poolSize=0;
	
	/**
	 * 
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException
	{
		MonteCarlo Controller = new MonteCarlo();
		Window fenetre = new Window();
		//Window fenetre = new Window(Controller);
	}
	
	/**
	 * (Sequential) Calculation of a configuration relatively to the Monte Carlo method.
	 * @param conf
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public static double SingleThreadingSimulation(Config conf) throws InterruptedException, ExecutionException
	{
		System.out.println("Single Threaded Simulation");
		MonteCarloSequentialSimulation simulator = new MonteCarloSequentialSimulation();
		
		System.out.println("Simulation parameters: " +conf.CallPutFlag +" " +conf.Price_S +" "
				+conf.StrikePrice_X +" " +conf.TimeToMaturity_T +" " +conf.InterestRate_r +" "
				+conf.CarryRateCost_b +" " +conf.UnderlyingAssetVolatility_v +" "
				+conf.nSteps +" " +conf.nSimulations); 
		
		simulator.timeAndComputeValue(conf.CallPutFlag.toString(), conf.Price_S, 
				conf.StrikePrice_X, conf.TimeToMaturity_T, conf.InterestRate_r,
				conf.CarryRateCost_b,conf.UnderlyingAssetVolatility_v, conf.nSteps, conf.nSimulations);
		
		MonteCarlo.result=simulator.result;
		MonteCarlo.timeResult=simulator.SimulationTime;
		
		return simulator.result;
	}
	
	/**
	 * (Multi-Threading) Calculation of a configuration relatively to the Monte Carlo method.
	 * @param conf
	 * @return
	 * @throws InterruptedException
	 * @throws ExecutionException
	 */
	public static double MultiThreadingSimulation(Config conf) throws InterruptedException, ExecutionException
	{
		System.out.println("Multi Threaded Simulation");
		MonteCarloThreadedSimulation simulator = new MonteCarloThreadedSimulation();
		
		System.out.println("Simulation parameters: " +conf.CallPutFlag +" " +conf.Price_S +" "
				+conf.StrikePrice_X +" " +conf.TimeToMaturity_T +" " +conf.InterestRate_r +" "
				+conf.CarryRateCost_b +" " +conf.UnderlyingAssetVolatility_v +" "
				+conf.nSteps +" " +conf.nSimulations); 
		
		simulator.timeAndComputeValue(conf.CallPutFlag, conf.Price_S, 
				conf.StrikePrice_X, conf.TimeToMaturity_T, conf.InterestRate_r,
				conf.CarryRateCost_b, conf.UnderlyingAssetVolatility_v, conf.nSteps, conf.nSimulations);
		
		MonteCarlo.coresNb=simulator.numberOfCores;
		MonteCarlo.poolSize=simulator.poolSize;
		MonteCarlo.result=simulator.result;
		MonteCarlo.timeResult=simulator.SimulationTime;
		
		return simulator.result;
	}
}
